<script setup lang="ts">
import type { SimEngineTableData } from "@/common/apis/engine-library/type"
import type { UploadScnInfo } from "@/common/apis/scn/type"
import type { UploadType } from "@@/constants/other-keys"
import type { FormInstance, FormRules, UploadUserFile } from "element-plus"
import { getSimEngineOptionsApi } from "@/common/apis/engine-library"
import { importZipApi } from "@/common/apis/scn"
import { getProjectId } from "@/common/utils/cache/local-storage"
import UploadFolder from "@@/components/UploadFolder/index.vue"
import { filesToZip } from "@@/utils/fileUtils"
import { ElMessage, ElMessageBox } from "element-plus"
import { cloneDeep, isEqual } from "lodash-es"
import { ref, watch } from "vue"

interface Props {
  visible: boolean
}

const props = defineProps<Props>()
const emit = defineEmits(["closeDialog"])
const selectedEngine = ref<SimEngineTableData[]>([])
const DEFAULT_FORM_DATA: UploadScnInfo = {
  scnName: "",
  file: undefined,
  fileName: "",
  description: undefined,
  pId: getProjectId(),
  engineId: undefined
}
const dialogVisible = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<UploadScnInfo>(cloneDeep(DEFAULT_FORM_DATA))
const formRules: FormRules<UploadScnInfo> = {
  scnName: [{ required: true, trigger: "blur", message: "请输入想定名称" }],
  fileName: [{ required: true, trigger: "change", message: "选择文件" }]
}
const fileList = ref<UploadUserFile[]>([])
const loading = ref<boolean>(false)
const detailLoading = ref<boolean>(false)
const uploadType = ref<UploadType>()

function showDialog() {
  formRef.value?.resetFields()
  fileList.value = []
  getSimEngineOptions()
}
function closeDialog() {
  formRef.value?.resetFields()
  emit("closeDialog", undefined)
}
async function getParam(): Promise<FormData> {
  return new Promise(async (resolve) => {
    const params = new FormData()
    params.append("scnName", formData.value.scnName)
    formData.value.description && params.append("description", formData.value.description)
    formData.value.pId && params.append("pId", formData.value.pId)
    formData.value.engineId && params.append("engineId", formData.value.engineId)
    if (uploadType.value !== undefined && fileList.value.length > 0) {
      if (uploadType.value === "Folder") {
        // 压缩zip
        const files = fileList.value as File[]
        const fileBlob = await filesToZip(files)
        params.append("file", fileBlob, `${formData.value.fileName}.zip`)
      }
      if (uploadType.value === "File") {
        const files = fileList.value as UploadUserFile[]
        params.append("file", files[0].raw as Blob)
      }
    }
    resolve(params)
  })
}
function handleConfirm() {
  formRef.value?.validate(async (valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    const params: FormData = await getParam()
    importZipApi(params)
      .then(() => {
        ElMessage.success("操作成功")
        emit("closeDialog", "refresh")
      })
      .finally(() => {
        loading.value = false
      })
  })
}
function handleCloseTip(done: () => void) {
  // 校验值是否相同
  if (isEqual(DEFAULT_FORM_DATA, formData.value)) {
    closeDialog()
    done()
    return
  }
  ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
    done()
  })
}
function getSimEngineOptions() {
  getSimEngineOptionsApi().then(({ data }) => {
    selectedEngine.value = data
  })
}
watch(
  () => [props.visible],
  () => {
    dialogVisible.value = props.visible
    if (props.visible) {
      showDialog()
    }
  }
)
watch(
  () => fileList.value,
  () => {
    if (fileList.value.length > 0) {
      formData.value.fileName = fileList.value[0].name
    }
  }
)
watch(
  () => fileList.value,
  () => {
    if (uploadType.value != undefined && fileList.value.length > 0) {
      if (uploadType.value == "File") {
        const files = fileList.value as UploadUserFile[]
        formData.value.fileName = files[0].name
      }
      if (uploadType.value == "Folder") {
        // 文件夹
        const files = fileList.value as File[]
        const relativePath = files[0].webkitRelativePath
        const folderName = relativePath && relativePath.split("/")[0]
        formData.value.fileName = folderName
      }
    } else {
      formData.value.fileName = ""
    }
  },
  { deep: true }
)
getSimEngineOptions()
</script>

<template>
  <el-drawer
    v-model="dialogVisible"
    direction="rtl"
    size="600px"
    :before-close="handleCloseTip"
    :show-close="false"
    :append-to-body="true"
    @close-auto-focus="closeDialog"
    @close="closeDialog"
  >
    <template #header>
      <div class="drawer-header">
        <h4>上传想定</h4>
      </div>
    </template>
    <template #default>
      <el-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        width="600"
        label-width="100px"
        label-position="right"
        :close-on-click-modal="false"
        v-loading="detailLoading"
      >
        <el-form-item label="想定名称" prop="scnName">
          <el-input v-model="formData.scnName" autocomplete="off" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="想定文件" prop="fileName">
          <UploadFolder
            accept=".zip"
            :file-name="formData.fileName"
            v-model:upload-type="uploadType"
            v-model:upload-files="fileList"
          />
        </el-form-item>
        <el-form-item label="仿真引擎" prop="engineId">
          <el-select v-model="formData.engineId" placeholder="请选择仿真引擎">
            <el-option
              v-for="item in selectedEngine" :key="item.sim_engine_id" :label="item.sim_engine_name"
              :value="item.sim_engine_id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="formData.description"
            :rows="3"
            type="textarea"
            placeholder="请输入"
            maxlength="600"
          />
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button plain @click="closeDialog">
          取 消
        </el-button>
        <el-button :loading="loading" type="primary" v-throttle="() => handleConfirm()">
          确 定
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>

<style lang="scss" scoped>
.upload-demo {
  width: 100% !important;
}
:deep(.el-upload.el-upload--text) {
  width: 100% !important;
}
</style>
